<?php

class LeaveController extends Controller {

	/**
	 * @var string the default layout for the views.
	 * Defaults to '//layouts/column2', meaning
	 * using two-column layout. See 'protected/views/layouts/column2.php'.
	 */
	public $layout = '//layouts/column2';

	/**
	 * @return array action filters
	 */
	public function filters() {
		return array(
			'rights',
		);
	}

	public function allowedActions() {
		return '_history, _getBalance, _getQuota, request, cancel, view';
	}

	/**
	 * Displays a particular model.
	 * @param integer $id the ID of the model to be displayed
	 */
	public function actionView($id) {
		$this->render('view', array(
			'model'=>$this->loadModel($id),
		));
	}

	/**
	 * Creates a new model.
	 * If creation is successful, the browser will be redirected to the 'view'
	 * page.
	 */
	public function actionCreate() {
		$model = new Leave;

		$this->performAjaxValidation($model);

		if (isset($_POST['Leave'])) {
			$model->attributes = $_POST['Leave'];
			$updateEmployee = false;
			if ($model->employeeId) {
				$employee = Employee::model()->findByPk($model->employeeId);
				if ($employee) {
					$balance = $employee->leaveBalance;
					if ($model->name == Leave::NAME_ANNUALY) {
						$model->balance = $balance - $model->debit;
					} else {
						$model->balance = $balance;
					}
					if ($model->status == Leave::STATUS_APPROVED_MANAGEMENT) {
						$employee->leaveBalance = $model->balance;
						$updateEmployee = true;
					}
				}
			}
			$trans = Yii::app()->db->beginTransaction();
			$saved = $model->save();
			if ($saved) {
				if ($updateEmployee) {
					$saved = $employee->save();
				}
			}
			if ($saved) {
				if ((!YII_DEBUG) && $model->name == Leave::NAME_ANNUALY) {
					$approved = Leave::STATUS_APPROVED_SUPERVISOR;
					if ($model->status == Leave::STATUS_PENDING) {
						$model->sendRequestSupervisorNotification();
					} elseif ($model->status == $approved) {
						$model->sendRequestManagementNotificaton();
					}
				}
				$trans->commit();
				$value = 'Request created successfully.';
				Yii::app()->user->setFlash('success', $value);
				$this->redirect(array('view', 'id'=>$model->id));
			}
		} else {
			$model->status = Leave::STATUS_PENDING;
		}

		$this->render('create', array('model'=>$model));
	}

	/**
	 * Updates a particular model.
	 * If update is successful, the browser will be redirected to the 'view'
	 * page.
	 * @param integer $id the ID of the model to be updated
	 */
	public function actionUpdate($id) {
		$model = $this->loadModel($id);

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if (isset($_POST['Leave'])) {
			$model->attributes = $_POST['Leave'];
			if ($model->save()) {
				$value = 'Request updated successfully.';
				Yii::app()->user->setFlash('success', $value);
				$this->redirect(array('view', 'id'=>$model->id));
			}
		}

		$this->render('update', array(
			'model'=>$model,
		));
	}

	/**
	 * Deletes a particular model.
	 * If deletion is successful, the browser will be redirected to the 'admin'
	 * page.
	 * @param integer $id the ID of the model to be deleted
	 */
	public function actionDelete($id) {
		if (Yii::app()->request->isPostRequest) {
			// we only allow deletion via POST request
			$this->loadModel($id)->delete();

			// if AJAX request (triggered by deletion via admin grid view), we
			// should not redirect the browser
			if (!isset($_GET['ajax'])) {
				$set = isset($_POST['returnUrl']);
				$this->redirect($set ? $_POST['returnUrl'] : array('admin'));
			}
		} else {
			throw new CHttpException(
				400, 'Invalid request. Please do not repeat this request again.'
			);
		}
	}

	/**
	 * Lists all models.
	 */
	public function actionIndex() {
		$model = new Leave('search');
		$model->unsetAttributes();  // clear any default values
		if (isset($_GET['Leave'])) {
			$model->attributes = $_GET['Leave'];
		}

		$this->render('index', array('model'=>$model));
	}

	/**
	 * Manages all models.
	 */
	public function actionAdmin() {
		$model = new Leave('search');
		$model->unsetAttributes();  // clear any default values
		if (isset($_GET['Leave']))
			$model->attributes = $_GET['Leave'];

		$this->render('admin', array(
			'model'=>$model,
		));
	}

	/**
	 * Returns the data model based on the primary key given in the GET variable
	 * If the data model is not found, an HTTP exception will be raised.
	 * @param integer the ID of the model to be loaded
	 */
	public function loadModel($id) {
		$model = Leave::model()->findByPk($id);
		if ($model === null) {
			throw new CHttpException(404, 'The requested page does not exist.');
		}
		return $model;
	}

	/**
	 * Performs the AJAX validation.
	 * @param CModel the model to be validated
	 */
	protected function performAjaxValidation($model) {
		if (isset($_POST['ajax']) && $_POST['ajax'] === 'leave-form') {
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}
	}

	public function action_history($employeeId) {
		$config = array(
			'criteria'=>array(
				'condition'=>'employeeId = :employeeId AND status <> :status',
				'params'=>array(
					':employeeId'=>$employeeId,
					':status'=>Leave::STATUS_PENDING,
				),
				'order'=>'start DESC',
			),
		);
		$dataProvider = new CActiveDataProvider('Leave', $config);
		$employee = Employee::model()->findByPk($employeeId);
		$data = array(
			'dataProvider'=>$dataProvider,
			'employee'=>$employee,
		);
		$this->renderPartial('_history', $data, false, true);
	}

	public function action_getBalance($employeeId) {
		$employee = Employee::model()->findByPk($employeeId);
		$data = array('balance'=>$employee->leaveBalance);
		echo CJSON::encode($data);
		Yii::app()->end();
	}

	public function action_getQuota($name, $employeeId) {
		switch ($name) {
			case Leave::NAME_MATERNITY:
				if ($employeeId) {
					$employee = Employee::model()->findByPk($employeeId);
					if ($employee) {
						if ($employee->gender == Employee::GENDER_FEMALE) {
							$quota = 90;
							break;
						}
						$quota = 2;
					}
				}
				$quota = 2;
				break;
			case Leave::NAME_MARRIAGE:
				$quota = 5;
				break;
			default:
				$quota = 1;
				break;
		}
		$data = array('quota'=>$quota);
		echo CJSON::encode($data);
		Yii::app()->end();
	}

	public function getMenu() {
		if (!$this->_menu) {
			$user = Yii::app()->user;
			$menu = array();
			$controller = 'Leave';
			$action = $this->action->id;
			$menu[] = array(
				'label'=>"List $controller",
				'url'=>array('index'),
				'visible'=>$action != 'index' &&
				$user->checkAccess('Leave.Index'),
			);
			$menu[] = array(
				'label'=>"Create $controller",
				'url'=>array('create'),
				'visible'=>$action != 'create' &&
				$user->checkAccess('Leave.Create'),
			);
			if (isset($_GET['id'])) {
				$model = $this->loadModel($_GET['id']);
				$menu = array_merge($menu, $model->getMenu($action));
			}
			$menu[] = array(
				'label'=>"Manage $controller",
				'url'=>array('admin'),
				'visible'=>$action != 'admin' &&
				$user->checkAccess('Leave.Admin'),
			);
			$menu[] = array(
				'label'=>"Mass $controller",
				'url'=>array('mass'),
				'visible'=>$action != 'mass' &&
				$user->checkAccess('Leave.Mass'),
			);
			$menu[] = array(
				'label'=>"Reset Balance",
				'url'=>array('reset'),
				'visible'=>$action != 'reset' &&
				$user->checkAccess('Leave.Reset'),
			);
			$this->_menu = $menu;
		}
		return $this->_menu;
	}

	public function actionReset() {
		$confirmed = isset($_GET['confirm']);
		if ($confirmed) {
			$table = Employee::model()->tableName();
			$expression = new CDbExpression('leaveBalanceDefault');
			$columns = array(
				'leaveBalance'=>$expression,
			);
			Yii::app()->db->createCommand()
				->update($table, $columns);
			$this->render('resetComplete');
		} else {
			$this->render('resetConfirm');
		}
	}

	public function actionApprove($id) {
		$model = $this->loadModel($id);

		$user = Yii::app()->user;
		if ($model->status != Leave::STATUS_PENDING) {
			$value = 'Sorry, this leave request is alredy processed.';
			$user->setFlash('error', $value);
			$this->redirect(array('view', 'id'=>$id));
		}

		if (!$user->isSuperuser) {
			if (!$user->isEmployee ||
				$user->employee->id != $model->employee->supervisorId
			) {
				$value = 'Sorry, only supervisor of the employee or super ';
				$value .= 'user may approve the request';
				$user->setFlash('error', $value);
				$this->redirect(array('view', 'id'=>$id));
			}
		}

		if (Yii::app()->request->isPostRequest) {
			if (isset($_POST['confirm'])) {
				$model->status = Leave::STATUS_APPROVED_SUPERVISOR;
				if ($model->save()) {
					if (!YII_DEBUG) {
						$model->sendApprovalNotificaton();
						$model->sendRequestManagementNotificaton();
					}
					$value = 'Request approved successfully.';
					$user->setFlash('success', $value);
				} else {
					$value = 'Something broke.<br />';
					$value .= 'Request could not be approved.<br />';
					$value .= 'Please notify the developer.';
					$user->setFlash('error', $value);
				}
				$this->redirect(array('view', 'id'=>$id));
			}
		}
		$this->render('approve', array('model'=>$model));
	}

	public function actionReject($id) {
		$model = $this->loadModel($id);

		$user = Yii::app()->user;
		if ($model->status != Leave::STATUS_PENDING) {
			$value = 'Sorry, this leave request is alredy processed.';
			$user->setFlash('error', $value);
			$this->redirect(array('view', 'id'=>$id));
		}

		if (!$user->isSuperuser) {
			$condition = 'userId = :userId';
			$params = array(':userId'=>$user->id);
			$employee = Employee::model()->find($condition, $params);
			if (!$employee || $employee->id != $model->employee->supervisorId) {
				$value = 'Sorry, only supervisor of the employee or super ';
				$value .= 'user may reject the request';
				$user->setFlash('error', $value);
				$this->redirect(array('view', 'id'=>$id));
			}
		}

		if (Yii::app()->request->isPostRequest) {
			if (isset($_POST['confirm'])) {
				$model->status = Leave::STATUS_REJECTED_MANAGEMENT;
				if ($model->save()) {
					if (!YII_DEBUG) {
						$model->sendRejectionNotificaton();
					}
					$value = 'Request rejected successfully.';
					$user->setFlash('success', $value);
				} else {
					$value = 'Something broke.<br />';
					$value .= 'Request could not be rejected.<br />';
					$value .= 'Please notify the developer.';
					$user->setFlash('error', $value);
				}
				$this->redirect(array('view', 'id'=>$id));
			}
		}
		$this->render('reject', array('model'=>$model));
	}

	public function actionCancel($id) {
		$model = $this->loadModel($id);

		$user = Yii::app()->user;
		$statuses = array(
			Leave::STATUS_PENDING,
			Leave::STATUS_APPROVED_SUPERVISOR
		);
		if (array_search($model->status, $statuses) === false) {
			$value = 'Sorry, this leave request is alredy processed.';
			$user->setFlash('error', $value);
			$this->redirect(array('view', 'id'=>$id));
		}

		if (!$user->isSuperuser) {
			if ($model->employeeId != $user->id) {
				$value = 'Sorry, only the employee itself or super user may ';
				$value .= 'cancel the request';
				$user->setFlash('error', $value);
				$this->redirect(array('view', 'id'=>$id));
			}
		}

		if (Yii::app()->request->isPostRequest) {
			if (isset($_POST['confirm'])) {
				$model->status = Leave::STATUS_CANCELED;
				if ($model->save()) {
					$value = 'Request canceled successfully.';
					$user->setFlash('success', $value);
				} else {
					$value = 'Something broke.<br />';
					$value .= 'Request could not be canceled.<br />';
					$value .= 'Please notify the developer.';
					$user->setFlash('error', $value);
				}
				$this->redirect(array('view', 'id'=>$id));
			}
		}
		$this->render('cancel', array('model'=>$model));
	}

	public function actionRequest() {
		if (!Yii::app()->user->isEmployee) {
			throw new CHttpException(404, 'Only employee may request leave.');
		}

		$model = new Leave('request');
		$model->employeeId = Yii::app()->user->employee->id;

		$this->performAjaxValidation($model);

		if (isset($_POST['Leave'])) {
			$model->attributes = $_POST['Leave'];
			$model->name = Leave::NAME_ANNUALY;
			$model->status = Leave::STATUS_PENDING;
			$model->balance = Yii::app()->user->employee->leaveBalance;
			$model->balance -= $model->debit;
			if ($model->save()) {
				if (!YII_DEBUG) {
					$model->sendRequestSupervisorNotification();
				}
				$this->redirect(array('view', 'id'=>$model->id));
			}
		} else {
			$model->balance = Yii::app()->user->employee->leaveBalance;
		}

		$this->render('request', array('model'=>$model));
	}

	public function actionMass() {
		$model = new Leave('mass');

		if (isset($_POST['Leave'])) {
			$model->attributes = $_POST['Leave'];
			if ($model->validate()) {
				$user = Yii::app()->user;
				$trans = Yii::app()->db->beginTransaction();
				$ok = true;
				foreach ($model->employeeId as $employeeId) {
					$employee = Employee::model()->findByPk($employeeId);
					$employee->leaveBalance -= $model->debit;
					$ok = $employee->save();
					if ($ok) {
						$leave = new Leave();
						$leave->employeeId = $employeeId;
						$leave->name = Leave::NAME_ANNUALY;
						$leave->debit = $model->debit;
						$leave->start = $model->start;
						$leave->balance = $employee->leaveBalance;
						$leave->status = Leave::STATUS_APPROVED_MANAGEMENT;
						$leave->note = $model->note;
						$ok = $leave->save();
						if (!$ok) {
							$value = "Error while saving leave for employee ";
							$value .= "$employee->name.<br />";
							foreach ($leave->errors as $error) {
								foreach ($error as $v) {
									$value .= $v;
									$value .= '<br />';
								}
							}
							$user->setFlash('error', $value);
						}
					} else {
						$value = "Error while updating employee ";
						$value .= "$employee->name.<br />";
						foreach ($employee->errors as $error) {
							foreach ($error as $v) {
								$value .= $v;
								$value .= '<br />';
							}
						}
						$user->setFlash('error', $value);
					}
					if (!$ok)
						break;
				}
				if ($ok) {
					$trans->commit();
					$this->redirect(array('index'));
				} else {
					$trans->rollback();
				}
			}
		}

		$this->render('mass', array('model'=>$model));
	}

	public function actionConsent($id) {
		$model = $this->loadModel($id);

		$user = Yii::app()->user;
		if ($model->status != Leave::STATUS_APPROVED_SUPERVISOR) {
			$value = 'Sorry, this leave request is not approved by supervisor.';
			$user->setFlash('error', $value);
			$this->redirect(array('view', 'id'=>$id));
		}

		if (!$user->isSuperuser) {
			if (!$user->isEmployee || !$user->employee->isManagement) {
				$value = 'Sorry, only management may consent the request';
				$user->setFlash('error', $value);
				$this->redirect(array('view', 'id'=>$id));
			}
		}

		if (Yii::app()->request->isPostRequest) {
			if (isset($_POST['confirm'])) {
				$model->status = Leave::STATUS_APPROVED_MANAGEMENT;
				if ($model->name == Leave::NAME_ANNUALY) {
					$model->employee->leaveBalance -= $model->debit;
					$model->balance = $model->employee->leaveBalance;
				}
				$trans = Yii::app()->db->beginTransaction();
				if ($model->employee->save() && $model->save()) {
					if (!YII_DEBUG) {
						$model->sendConsentNotification();
					}
					$value = 'Request consented successfully.';
					$user->setFlash('success', $value);
					$trans->commit();
				} else {
					$trans->rollback();
				}
				$this->redirect(array('view', 'id'=>$id));
			}
		}
		$this->render('consent', array('model'=>$model));
	}

	public function actionNegate($id) {
		$model = $this->loadModel($id);

		$user = Yii::app()->user;
		if ($model->status != Leave::STATUS_APPROVED_SUPERVISOR) {
			$value = 'Sorry, this leave request is not approved by supervisor.';
			$user->setFlash('error', $value);
			$this->redirect(array('view', 'id'=>$id));
		}

		if (!$user->isSuperuser) {
			if (!$user->isEmployee || !$user->employee->isManagement) {
				$value = 'Sorry, only management may negate the request';
				$user->setFlash('error', $value);
				$this->redirect(array('view', 'id'=>$id));
			}
		}

		if (Yii::app()->request->isPostRequest) {
			if (isset($_POST['confirm'])) {
				$model->status = Leave::STATUS_REJECTED_MANAGEMENT;
				if ($model->save()) {
					if (!YII_DEBUG) {
						$model->sendRejectionNotificaton();
					}
					$value = 'Request negated successfully.';
					$user->setFlash('success', $value);
				} else {
					$value = 'Something broke.<br />';
					$value .= 'Request could not be negated.<br />';
					$value .= 'Please notify the developer.';
					$user->setFlash('error', $value);
				}
				$this->redirect(array('view', 'id'=>$id));
			}
		}
		$this->render('negate', array('model'=>$model));
	}

}
